﻿using System;
using System.Collections.Generic;
using System.Data;
using DataScripter.Database;
using DataScripter.Scripting;
using DataScripter.Scripting.InputSources;
using DataScripter.Scripting.Output;
using DataScripter.Scripting.Output.Sql.SqlServer;
using DataScripter.Scripting.OutputDestinations;
using DataScripter.Scripting.ScriptDefinitions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace DataScripter.UnitTests.EngineTests.Script
{
    [TestClass]
    public class WhenEngineHasOneRequestAndScriptIsCalled
    {
        private readonly IScriptDefinition _scriptDefinition;
        private readonly IScriptResult _scriptResult;
        private readonly SqlServerScriptOptions _options;
        private readonly Mock<IOutputProducer> _producerMock;
        private readonly Engine _engine;

        public WhenEngineHasOneRequestAndScriptIsCalled()
        {
            Mock<IDatabaseStructure> structureMock = new Mock<IDatabaseStructure>();
            Mock<ITableStructure> tableStructureMock = new Mock<ITableStructure>();

            structureMock.Setup(s => s.GetTable("abc")).Returns(tableStructureMock.Object);
            tableStructureMock.Setup(s => s.ForeignKeys).Returns(new List<IForeignKey>());

            Mock<IDataProducer> dataProducerMock = new Mock<IDataProducer>();
            _producerMock = new Mock<IOutputProducer>();

            _engine = new Engine();

            IInputSource inputSource = new SqlServerInputSource("", _engine);
            _engine.RegisterType(inputSource);
            IOutputDestination outputDestination = new FileOutputDestination("", _engine);
            _engine.RegisterType(outputDestination);

            _engine.RegisterType(structureMock.Object);
            inputSource.RegisterType(dataProducerMock.Object);
            outputDestination.RegisterType(_producerMock.Object);

            _scriptDefinition = new ScriptDefinition("", _engine);
            _engine.RegisterType(_scriptDefinition);


            _scriptDefinition.RequestScript("abc");

            _options = new SqlServerScriptOptions(SqlScriptType.Insert)
            {
                ScriptOutputType = ScriptOutputType.Memory
            };

            _scriptResult = _engine.Script(_options);
        }

        [TestMethod]
        public void InitializeShouldHaveBeenCalled()
        {
            _producerMock.Verify(p => p.InitializeScript(_engine, _scriptResult));
        }

        [TestMethod]
        public void FinalizeShouldHaveBeenCalled()
        {
            _producerMock.Verify(p => p.FinalizeScript());
        }

        [TestMethod]
        public void ProduceScriptShouldNotHaveBeenCalled()
        {
            _producerMock.Verify(p => p.ProduceOutput(It.IsAny<IDataReader>(), It.IsAny<ITableScriptRequest>()), Times.Once());
        }
    }
}
